/**
 * @author guan
 * @date 12/22/2021
 */
package com.guan.entity;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.IntStream;

public class ThreadPool {

    // 使用阻塞队列在线程池中实现 生产者-消费者 模式
    private BlockingQueue<Runnable> workingQueue;

    //  默认阻塞队列的大小
    private static final int DEFAULT_WORKINGQUEUE_SIZE = 5;

    // 使用 List 来存储线程池内部的工作线程
    private List<WorkThread> workingThreads = new ArrayList<WorkThread>();

    /**
     * 传入线程池的大小和阻塞队列
     * @param poolSize
     * @param workingQueue
     */
    public ThreadPool(int poolSize, BlockingQueue<Runnable> workingQueue) {
        this.workingQueue = workingQueue;
        // 将 poolSize 个工作线程创建并且加入到 workedQueue 中
        // 不能使用 for 循环
        IntStream.range(0, poolSize).forEach((i) -> {
            WorkThread workThread = new WorkThread();
            workThread.start();
            workingThreads.add(workThread);
        });
    }

    /**
     * 传入线程池大小
     * @param poolSize
     */
    public ThreadPool(int poolSize) {
        this(poolSize, new LinkedBlockingQueue<>(DEFAULT_WORKINGQUEUE_SIZE));
    }

    /**
     * 执行任务
     * @param task
     */
    public void execute(Runnable task) {
        try {
            workingQueue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 内部类 WorkThread 模拟线程池中的工作线程
     * 主要用来 消费 workedQueue 中的任务并执行
     *  不断尝试从 workedQueue 中获取任务，使用 while(true)
     */
    class WorkThread extends Thread {

        @Override
        public void run() {
            while (true) {
                // 没有任务时会阻塞
                try {
                    // 尝试从 workingQueue 中取出可执行任务并执行
                    Runnable workTask = workingQueue.take();
                    workTask.run();
                } catch(InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }



}

